package com.katesoft.scale4j.rttp.hibernate;

import java.util.Properties;

import org.hibernate.cache.CacheDataDescription;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.CollectionRegion;
import org.hibernate.cache.EntityRegion;
import org.hibernate.cache.QueryResultsRegion;
import org.hibernate.cache.RegionFactory;
import org.hibernate.cache.TimestampsRegion;
import org.hibernate.cache.access.AccessType;
import org.hibernate.cfg.Settings;
import org.springframework.beans.factory.annotation.Required;

import com.hazelcast.hibernate.HazelcastTimestamper;
import com.hazelcast.hibernate.collection.HazelcastCollectionRegion;
import com.hazelcast.hibernate.entity.HazelcastEntityRegion;
import com.hazelcast.hibernate.query.HazelcastQueryResultsRegion;
import com.hazelcast.hibernate.timestamp.HazelcastTimestampsRegion;
import com.katesoft.scale4j.log.LogFactory;
import com.katesoft.scale4j.log.Logger;

/**
 * This class provides hibernate second level cache solution.
 * 
 * @author kate2007
 */
public class RttpHibernateCacheRegionFactory implements RegionFactory {
   private final Logger logger = LogFactory.getLogger(RttpHibernateCacheRegionFactory.class);
   private SpringHazelcastBridge springHazelcastBridge;

   public RttpHibernateCacheRegionFactory() {
      super();
   }

   public RttpHibernateCacheRegionFactory(@SuppressWarnings("unused") final Properties properties) {
      this();
   }

   @Override
   public AccessType getDefaultAccessType() {
      return AccessType.READ_WRITE;
   }

   @Override
   public long nextTimestamp() {
      return HazelcastTimestamper.nextTimestamp(springHazelcastBridge.getHazelcastInstance());
   }

   @Override
   public void start(@SuppressWarnings("unused") Settings settings, Properties properties)
            throws CacheException {
      logger.info("Starting up HazelcastCacheRegionFactory...");
      springHazelcastBridge.getHazelcastLauncher().loadInstance(properties);
   }

   @Override
   public void stop() {
      logger.info("Shutting down RttpHibernateCacheRegionFactory...");
      springHazelcastBridge.getHazelcastLauncher().stop();
   }

   @Override
   public boolean isMinimalPutsEnabledByDefault() {
      return false;
   }

   @Override
   public CollectionRegion buildCollectionRegion(String regionName,
            @SuppressWarnings("unused") Properties properties, CacheDataDescription metadata)
            throws CacheException {
      return new HazelcastCollectionRegion(springHazelcastBridge.getHazelcastInstance(),
               regionName, metadata);
   }

   @Override
   public EntityRegion buildEntityRegion(String regionName,
            @SuppressWarnings("unused") Properties properties, CacheDataDescription metadata)
            throws CacheException {
      return new HazelcastEntityRegion(springHazelcastBridge.getHazelcastInstance(), regionName,
               metadata);
   }

   @Override
   public QueryResultsRegion buildQueryResultsRegion(String regionName,
            @SuppressWarnings("unused") Properties properties) throws CacheException {
      return new HazelcastQueryResultsRegion(springHazelcastBridge.getHazelcastInstance(),
               regionName);
   }

   @Override
   public TimestampsRegion buildTimestampsRegion(String regionName,
            @SuppressWarnings("unused") Properties properties) throws CacheException {
      return new HazelcastTimestampsRegion(springHazelcastBridge.getHazelcastInstance(), regionName);
   }

   @Required
   public void setSpringHazelcastBridge(SpringHazelcastBridge springHazelcastBridge) {
      this.springHazelcastBridge = springHazelcastBridge;
      logger.info("spring hazelcast bridge [%s] registered", springHazelcastBridge);
   }
}
